package org.kingtop.mybatis.util;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;

import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.kingtop.mybatis.mapper.IBaseDaoMapper;

public class ReflectUtil {

	/**
	 * 获取IBaseDaoMapper接口中的T的类
	 * 
	 * @author 陈金波
	 * @date 2018年1月2日 下午3:42:40
	 * @param mapperClass
	 *            dao接口
	 * @return
	 * @return Class<?>
	 */
	public static Class<?> extractModelClass(Class<?> mapperClass) {
		Type[] types = mapperClass.getGenericInterfaces();
		ParameterizedType target = null;
		for (Type type : types) {
			if (type instanceof ParameterizedType
					&& ((ParameterizedType) type).getRawType().equals(IBaseDaoMapper.class)) {
				target = (ParameterizedType) type;
				break;
			}
		}
		if (target == null) {
			return null;
		}
		Type[] parameters = target.getActualTypeArguments();
		Class<?> modelClass = (Class<?>) parameters[0];
		return modelClass;
	}

	/**
	 * 提取方法所在类的接口中的T的类
	 * 
	 * @author 陈金波
	 * @date 2018年1月5日 下午8:57:36
	 * @param method
	 * @return
	 * @return Class<?>
	 */
	public static Class<?> extractModelClass(Method method) {
		Class<?> mapperClass = method.getDeclaringClass();
		return extractModelClass(mapperClass);
	}

	/**
	 * <p>
	 * 获得真正的处理对象,可能多层代理.适合StatementHandler
	 * </p>
	 */
	public static Object realTarget(Object target) {
		if (Proxy.isProxyClass(target.getClass())) {
			MetaObject metaObject = SystemMetaObject.forObject(target);
			return realTarget(metaObject.getValue("h.target"));
		}
		return target;
	}

}
